package cn.biplam.front.component.data.tree.treebase;

import cn.biplam.common.ajxcode.SystemCode.TreeDcIndexCode;
import cn.biplam.common.bean.md.IndexTable;
import cn.biplam.common.client.DataFilter;
import cn.biplam.common.client.Operator;
import cn.biplam.common.client.OperatorResult;
import cn.biplam.common.opcode.SysManageCode.TreeIndexCode;
import cn.biplam.common.opcode.mdManage.TreeCode.TreeOptCode;
import cn.biplam.common.paramters.SysCaption;
import cn.biplam.common.paramters.SysName;
import cn.biplam.common.paramters.TreeParam;
import cn.biplam.common.tools.TOOLS;
import cn.biplam.common.wrapper.ErrorMessage;
import cn.biplam.common.wrapper.KvMap;
import cn.biplam.common.wrapper.UserInfo;
import cn.biplam.common.wrapper.tree.TreeIndexFields;
import cn.biplam.front.component.data.common.CaptionComp;
import cn.biplam.front.component.data.tree.TreeData;
import cn.biplam.front.component.data.tree.TreeIndexData;
import cn.biplam.front.component.data.tree.Virtual_Node_Name_From;
import cn.biplam.front.component.data.tree.treebase.Tree_Type.Tree_DC_Type;
import cn.biplam.front.component.data.tree.treebase.Tree_Type.Tree_NodeType_Commen;
import cn.biplam.front.html.HtmlDiv;
import cn.biplam.front.html.HtmlValue;
import cn.biplam.front.html.base.HtmlWindow;
import cn.biplam.front.html.base.Const.Window_Event;
import cn.biplam.front.htmlscript.script.PopupScript;
import cn.biplam.front.htmlscript.script.ScriptCustomer;
import cn.biplam.front.htmlscript.script.ScriptTreeNew;
import cn.biplam.front.htmlscript.script.ScriptPrompt.Close_Prompt;
import cn.biplam.front.template.base.SimpleInput;
import cn.biplam.front.template.base.SimpleTextArea;
import cn.biplam.front.template.base.Text;
import cn.biplam.front.template.control.Confirm;
import cn.biplam.front.template.control.FlatTable;

/**
 * 索引表树的DC
 *   <li>返回树所需要的数据TreeData
 * @author WangSong 2009-9-30上午09:10:32
 * @version 1.0
 */
public class TreeDcIndex extends TreeDC{
	
	/**当前容器的ID */
	public static final String cId = "8111";
	/**取树显示数据的参数名*/
	/** 索引表名*/
	public String tableName;
	/** 虚根名称*/
	private String VirtualRootName;
	/** 节点容器id*/
	private String nodeCId;
	/** 展开的节点id*/
	private String nodeId;
	/** 展开的节点级别*/
	private String nodeLevel;
	/** 节点向下展开几级*/
	private String levelDown;
	/** 真实节点id*/
	private String realId;
	/** 父亲是否有弟弟*/
	private String parentsHaveLBrother;
	/**当前节点是否有哥哥 */
	private String haveBrother;
	/**当前节点是否有弟弟 */
	private String haveLBrother;
	/** 取节点名字的operatorId*/
	private String textOperatorId;
	
	/**通用的增删改参数*/
	/** 添加的级联操作operatorId*/
	private String operatorIdAddNew;
	/** 修改的级联操作operatorId*/
	private String operatorIdModify;
	/** 删除的级联操作operatorId*/
	private String operatorIdDelete;
	/** 树的节点类型*/
	private String nodeType;
	/** 索引表字段对象*/
	private TreeIndexFields field;
	/** 调用树的父容器id*/
	private String pcid;
	/** 树VC的行为id*/
	private String aId;
	
	/** 获取节点过滤列表操作OperatorID */
	private String filterOperatorId = null;
	/** 节点过滤条件 */
	private DataFilter nodeFilter;
	/** 虚拟根节点名称来源 */
	private Virtual_Node_Name_From virtualNameFrom;
	
	/**
	 * 无参构造,ajx调用时使用
	 */
	public TreeDcIndex(){
		
	}
	
	/**
	 * 构造函数
	 * @param mUser 用户信息
	 * @param tableName 索引表名
	 * @param VirtualRootName 虚根名称
	 * @throws ErrorMessage 
	 */
	public TreeDcIndex(UserInfo mUser,
	           		   String tableName,
	           		   String VirtualRootName) throws ErrorMessage{
		this(mUser,tableName,VirtualRootName,"-1","0","1",null,null,null);
	}
	
	/**
	 * 构造函数
	 * @param mUser 用户信息
	 * @param tableName 索引表名
	 * @param VirtualRootName 虚根名称
	 * @param levelDown 向下展开级别
	 * @throws ErrorMessage 
	 */
	public TreeDcIndex(UserInfo mUser,
	           		   String tableName,
	           		   String VirtualRootName,
	           		   String levelDown) throws ErrorMessage{
		this(mUser,tableName,VirtualRootName,"-1","0",levelDown,null,null,null);
	}
	
	/**
	 * 构造函数
	 * @param mUser 用户信息
	 * @param tableName 索引表名
	 * @param VirtualRootName 虚根名称
	 * @param nodeId 节点ID
	 * @param levelDown 向下展开级别
	 * @throws ErrorMessage 
	 */
	public TreeDcIndex(UserInfo mUser,
	           		   String tableName,
	           		   String VirtualRootName,
	           		   String nodeId,
	           		   String levelDown) throws ErrorMessage{
		this(mUser,tableName,VirtualRootName,nodeId,"0",levelDown,null,null,null);
	}
	
	/**
	 * 构造方法(树展开时模版内部调用此构造方法)
	 * @param mUser    用户信息
	 * @param sHomeUrl 系统路径
	 * @param tableName 索引表名
	 * @param nodeType  树的节点类型
	 * @param VirtualRootName 虚根名称
	 * @param mTree 树模版对象
	 * @param pageId 顶级页面id(持久化树用)
	 * @param pcid 调用树的vc的容器的id
	 * @param aId 树Vc的行为id
	 * @throws ErrorMessage 
	 */
	public TreeDcIndex(UserInfo mUser,
			           String tableName,
			           String VirtualRootName,
			           String nodeId,
			           String nodeLevel,
			           String levelDown,
			           String haveBrother,
			           String haveLBrother,
			           String parentsHaveLBrother) throws ErrorMessage{
		this.mUser = mUser;
		this.tableName = tableName;
		this.VirtualRootName = VirtualRootName;
		this.nodeId = nodeId;
		this.nodeLevel = nodeLevel;
		this.levelDown = levelDown;
		this.haveBrother = haveBrother;
		this.haveLBrother = haveLBrother;
		this.parentsHaveLBrother = parentsHaveLBrother;
	}

	/**
	 *  设置父亲们是否有弟弟
	 * @param parentsHaveLBrother
	 */
	public void setParentsHaveLBrother(String parentsHaveLBrother){
		this.parentsHaveLBrother = parentsHaveLBrother;
	}
	
	/**
	 *  设置是否有弟弟
	 * @param haveLBrother
	 */
	public void setHaveLBrother(String haveLBrother){
		this.haveLBrother = haveLBrother;
	}
	
	/**
	 *  设置是否有哥哥
	 * @param haveBrother
	 */
	public void setHaveBrother(String haveBrother){
		this.haveBrother = haveBrother;
	}
	
	/**
	 *  设置向下级别
	 * @param levelDown
	 */
	public void setLevelDown(String levelDown){
		this.levelDown = levelDown;
	}
	
	/**
	 *  设置节点级别
	 * @param nodeLevel
	 */
	public void setNodeLevel(String nodeLevel){
		this.nodeLevel = nodeLevel;
	}
	
	/**
	 *  设置节点ID
	 * @param nodeId
	 */
	public void setNodeId(String nodeId){
		this.nodeId = nodeId;
	}
	
	/**
	 *  设置虚拟根节点描述信息来源类型（外面设置或数据库读取）
	 * @param type 描述信息来源类型(Virtual_Node_Name_From)
	 */
	public void setVirtualInfoFrom(Virtual_Node_Name_From type){
		this.virtualNameFrom = type;
	}
	
	/**
	 * 设置取指定节点的子树参数信息
	 * @param userID 用户ID
	 * @param nodeId 当前节点id
	 * @param nodeLevel 当前节点级别
	 * @param levelDown 向下取几级数据 -1 全部 0 当前  1 当前节点下1级 2当前节点向下2级 ... n当前节点向下n级
	 * @param parentsHaveLBrother 父亲们是否有弟弟
	 * @throws ErrorMessage
	 */
	public TreeData get() throws ErrorMessage{
		TreeIndexData tid = new TreeIndexData();

		tid.setData(tableName, mUser.getUserID(), nodeId,nodeLevel, levelDown,null,
				haveBrother,haveLBrother,parentsHaveLBrother);
		
		//设置虚根
		tid.setVirtualRootNode(VirtualRootName, null);
		tid.setLevelDown(TOOLS.stringToInt(levelDown));
		tid.setVirtualNodeVisiable(this.virtualNodeVisiable);
		//设置过滤参数操作OPID
		tid.setFilterOperator(filterOperatorId,this.nodeFilter);
		//设置虚拟根节点信息来源
		tid.setVirtualInfoFrom(this.virtualNameFrom);
		tid.create();
		tid.setTableName(tableName);
		return tid;
	}

	@Override
	public String getTableName() throws ErrorMessage {
		return tableName;
	}

	@Override
	public Tree_DC_Type getType() throws ErrorMessage {
		return Tree_DC_Type.TreeIndex;
	}
	
	@Override
	public String getOperatorId() throws ErrorMessage {
		return null;
	}

	@Override
	public String getRowId() throws ErrorMessage {
		return null;
	}
	
	@Override
	public String getField() throws ErrorMessage {
		return null;
	}
	
	/**
	 *  设置节点过滤列表操作OperatorID<BR>
	 *  树生成时，会调用该Operator，获取过滤的节点列表(仅在非叶子节点展开时进行过滤)<BR>
	 *  传给Operator操作的参数是:默认参数(当前节点ID)和IndexTableStruc.NODE_CODE<BR>
	 *  更多参数通过setNodeFilter传入DataFilter(不能占用默认参数)<BR>
	 *  Operator操作返回过滤节点结果集<BR>
	 *  附注:Operator操作的逻辑是依据当前节点ID,返回一个需要过滤的节点的列表<BR>
	 *  	树生成时比对当前返回的节点，如果ID在过滤列表内，则抛弃子节点<BR>
	 *  注意：过滤执行是在非叶子节点展开时，但可过滤的节点是所有下级节点，包括下级目录节点<BR>
	 *  获取过滤节点数据的操作接口是OperatorResult.getValue(IndexTableStruc.NODE_CODE)
	 * @param filterOperatorId 节点过滤列表操作OperatorID
	 */
	public void setFilterOperatorId(String filterOperatorId) {
		this.filterOperatorId = filterOperatorId;
	}
	
	/**
	 *   设置节点过滤列表操作
	 * @param nodeFilter 节点过滤条件： 过滤条件的默认参数oid(当前节点ID),NODE_CODE(节点真实ID)
	 */
	public void setNodeFilter(DataFilter nodeFilter){
		this.nodeFilter = nodeFilter;
	}
	
	/**
	 *  获取节点过滤列表操作OperatorID
	 * @param filterOperatorId 节点过滤列表操作OperatorID
	 */
	public String getFilterOperatorId() {
		return this.filterOperatorId;
	}
	
	@Override
	protected HtmlWindow ajxGet() throws ErrorMessage {
		getParam();
		if(actionId.equals(TreeDcIndexCode.Add_Theme)){
			return getAddPanel(mUser,Tree_NodeType_Commen.SubTheme.toString());
		}if(actionId.equals(TreeDcIndexCode.Add_Leaf)){
			return getAddPanel(mUser,Tree_NodeType_Commen.Leaf.toString());
		}else if(actionId.equals(TreeDcIndexCode.Edit)){
			return getEditPanel(mUser);
		}else if(actionId.equals(TreeDcIndexCode.Del)){
			return getDelPanel();
		}else if(actionId.equals(TreeDcIndexCode.Add_Opt)){
			return addOpt();
		}else if(actionId.equals(TreeDcIndexCode.Del_Opt)){
			return deleteOpt(); 
		}else if(actionId.equals(TreeDcIndexCode.Edit_Opt)){
			return editOpt();
		}else if(actionId.equals(TreeDcIndexCode.Left_Null)){
			return new HtmlDiv();
		}else{
			throw new ErrorMessage("Ajx Exchange outport not found:"+ actionId+" !");
		}
	}
	
	/**
	 * 获取编辑界面
	 * @param mUser 用户
	 * @return 返回业务对象主题内容编辑界面
	 * @throws ErrorMessage
	 */
	private HtmlWindow getEditPanel(UserInfo mUser) throws ErrorMessage{
		getTreeIndexFields();
		
		DataFilter filterIndex=new DataFilter();
		String[] record=recordId.split(",");
		filterIndex.put(field.getNodeId(), record[0]);
		filterIndex.put("table_name", tableName);
		OperatorResult sr=Operator.get(TreeIndexCode.Select_Node, mUser.getUserID(), filterIndex);
		String operatorType = sr.getValue(field.getOperatorType());
		HtmlWindow panel=_getPanel(mUser, sr,operatorType);
		ScriptCustomer.getSpSubmitCheckInput(panel,_getThemeEditCheck(),
				cId,TreeDcIndexCode.Edit_Opt,Close_Prompt.Close);
		return panel;
	}

	/**
	 * 获取添加界面
	 * @return 业务对象主题添加界面
	 * @throws ErrorMessage
	 */
	private HtmlWindow getAddPanel(UserInfo mUser,String operatorType) throws ErrorMessage{
		getTreeIndexFields();
		HtmlWindow panel=_getPanel(mUser,null,operatorType);
		ScriptCustomer.getSpSubmitCheckInput(panel,_getThemeEditCheck(),
				cId, TreeDcIndexCode.Add_Opt,Close_Prompt.Close);
		return panel;
	}
	
	/**
	 * 获取添加修改主题界面的检查条件
	 * @return
	 * @throws ErrorMessage 
	 */
	private KvMap<String, String> _getThemeEditCheck() throws ErrorMessage{
		KvMap<String, String> checkField = new KvMap<String, String>();
		checkField.put(TreeParam.NAME,"名称不能为空!");
		return checkField;
	}
	
	/**
	 * 获取删除界面
	 * @return 返回删除界面
	 * @throws ErrorMessage
	 */
	private HtmlWindow getDelPanel() throws ErrorMessage{
		getTreeIndexFields();
		DataFilter filterIndex=new DataFilter();

		filterIndex.put(field.getNodeId(), nodeId);
		filterIndex.put("table_name", tableName);
		OperatorResult sr=Operator.get(TreeIndexCode.Select_Node, mUser.getUserID(), filterIndex);
		String themeName = null;
		if(textOperatorId!=null && !"".equals(textOperatorId.trim())){
			themeName = getNodeText(textOperatorId, realId);
		}
		if(TOOLS.StringIsEmpty(themeName)){
			themeName=sr.getValue(field.getNodeName());
		}
		if(TOOLS.StringIsEmpty(themeName)){
			themeName = nodeId;
		}
		
		String operatorType = sr.getValue(field.getOperatorType());
		
		HtmlWindow win = null;
		//判断该节点是否有下级
		IndexTable boBean = IndexTable.getNewInstance(mUser.getUserID(),tableName,nodeId);
		if(boBean.getIsLeaf()){//是叶子节点
			/**创建删除提示*/
			StringBuilder sb = new StringBuilder();
			sb.append(CaptionComp.get(mUser, SysCaption.Confirm));
			sb.append(CaptionComp.get(mUser, SysCaption.Delete));
			sb.append(" ");
			sb.append(themeName);
			sb.append(" ?");
			
			/**生成提示信息窗口*/
			Confirm delete = new Confirm(sb.toString(),recordId);
			delete.bind(TreeDcIndexCode.Del_Opt);
			win=delete.get();
			
		}else{//有下级
			StringBuilder sb = new StringBuilder();
			sb.append(CaptionComp.get(mUser, SysCaption.Delete));
			sb.append(" ");
			sb.append(themeName);
			sb.append(" ");
			sb.append(CaptionComp.get(mUser, SysCaption.Cancel));
			Confirm delete = new Confirm(sb.toString(),recordId);
			HtmlWindow confirm=new Text(CaptionComp.get(mUser, SysCaption.CantDeleteTreeNode)).get();
			confirm.setFontColor("red");
			delete.put(confirm);
			win=delete.get();
			win.bind(SysName.PromptSubmitID,Window_Event.OnClick,PopupScript.cancel(SysName.PromptID));
		}
		
		
		win.put(new HtmlValue(null,"h,"+TreeParam.TABLE_NAME,tableName));
		win.put(new HtmlValue(null,"h,"+TreeParam.OPERATORID_DELETE,operatorIdDelete));
		win.put(new HtmlValue(null,"h,"+TreeParam.NODE_TYPE,nodeType));
		win.put(new HtmlValue(null,"h,"+TreeParam.TREE_PCID,pcid));
		win.put(new HtmlValue(null,"h,"+TreeParam.TREE_AID,aId));
		win.put(new HtmlValue(null,"h,"+TreeParam.OPERATOR_TYPE,operatorType));
		win.put(new HtmlValue(null,"h,"+TreeParam.NODE_TEXT_OPEERATORID,textOperatorId));
		win.put(new HtmlValue(null,"h,"+TreeParam.NODE_ID,nodeId));
		win.put(new HtmlValue(null,"h,"+TreeParam.NODE_REAL_ID,realId));
		win.put(new HtmlValue(null,"h,"+TreeParam.NODE_CONTARINER_ID,nodeCId));
		return win;
	}
	
	/**
	 * 获取业务对象主题添加和编辑表界面
	 * @param mUser 用户 
	 * @return 返回业务对象主题添加和编辑表界面
	 * @throws ErrorMessage
	 */
	private HtmlWindow _getPanel(UserInfo mUser,OperatorResult sr,String operatorType) throws ErrorMessage{
		getTreeIndexFields();
		String name="";
		String desc="";
		
		if(TOOLS.exist(sr)){
			name = sr.getValue(field.getNodeName());
			desc = sr.getValue(field.getNodeDesc());
			operatorType = sr.getValue(field.getOperatorType());
		}
		FlatTable table = new FlatTable(cId,recordId);
		table.setWidth("300");
		table.putTh("名称",0,0);
		table.putTd(new SimpleInput(TreeParam.NAME,"30",name).get(), 0, 1);
		table.putTh("描述",1,0);
		table.putTd(new SimpleTextArea(TreeParam.DESC,"30",desc).get(), 1, 1);
		table.setColSize(0, 8);
		
		HtmlWindow et = table.get();
		et.put(new HtmlValue(null,"h,"+TreeParam.TABLE_NAME,tableName));
		et.put(new HtmlValue(null,"h,"+TreeParam.OPERATORID_ADD,operatorIdAddNew));
		et.put(new HtmlValue(null,"h,"+TreeParam.OPERATORID_MODIFY,operatorIdModify));
		et.put(new HtmlValue(null,"h,"+TreeParam.NODE_TYPE,nodeType));
		et.put(new HtmlValue(null,"h,"+TreeParam.TREE_PCID,pcid));
		et.put(new HtmlValue(null,"h,"+TreeParam.TREE_AID,aId));
		et.put(new HtmlValue(null,"h,"+TreeParam.OPERATOR_TYPE,operatorType));
		et.put(new HtmlValue(null,"h,"+TreeParam.NODE_TEXT_OPEERATORID,textOperatorId));
		et.put(new HtmlValue(null,"h,"+TreeParam.NODE_ID,nodeId));
		et.put(new HtmlValue(null,"h,"+TreeParam.NODE_REAL_ID,realId));
		et.put(new HtmlValue(null,"h,"+TreeParam.NODE_CONTARINER_ID,nodeCId));
		
		return et;
	}
	
	/**
	 * 添加业务对象主题操作
	 * @return  刷新业务对象对象管理导航树脚本
	 * @throws ErrorMessage
	 */
	private HtmlWindow addOpt() throws ErrorMessage{
		getTreeIndexFields();
		HtmlWindow win=new HtmlDiv();
		String parentID=nodeId;
		DataFilter filter=new DataFilter();
		filter.putAll(params);
		filter.put(field.getNodeParent(),parentID);
		String nodeID=Operator.get(TreeOptCode.Insert, mUser.getUserID(), filter).getLastRowId();
		win.bind(ScriptTreeNew.getRefreshAdd(nodeCId, aId, nodeID));
		return win;
	}
	
	/**
	 * 修改业务对象主题操作
	 * 
	 * @return 刷新业务对象对象管理导航树脚本
	 * @throws ErrorMessage
	 */
	private HtmlWindow editOpt() throws ErrorMessage {
		getTreeIndexFields();
		HtmlWindow win = new HtmlDiv();
		DataFilter filter = new DataFilter();
		filter.put(field.getNodeId(), nodeId);
		filter.putAll(params);
		Operator.get(TreeOptCode.Update, mUser.getUserID(), filter);
		win.bind(ScriptTreeNew.getRefreshModify(nodeCId, aId));
		return win;
	}
	
	/**
	 * 删除业务对象主题数据操作
	 * @throws ErrorMessage
	 */
	private HtmlWindow deleteOpt() throws ErrorMessage{
		getTreeIndexFields();
		HtmlWindow win=new HtmlDiv();
		DataFilter filter=new DataFilter();
		String[] nodeInfo=recordId.split(",");
		filter.put(field.getNodeId(), nodeInfo[0]);
		filter.putAll(params);
		Operator.get(TreeOptCode.Delete, mUser.getUserID(), filter);
		win.bind(ScriptTreeNew.getRefreshDelete(nodeCId, aId));
		return win;
	}
	
	/**
	 * 取页面传来的参数
	 */
	private void getParam(){
		tableName = params.getByKey(TreeParam.TABLE_NAME);
		operatorIdAddNew = params.getByKey(TreeParam.OPERATORID_ADD);
		operatorIdModify = params.getByKey(TreeParam.OPERATORID_MODIFY);
		operatorIdDelete = params.getByKey(TreeParam.OPERATORID_DELETE);
		nodeType = params.getByKey(TreeParam.NODE_TYPE);
		pcid = params.getByKey(TreeParam.TREE_PCID);
		aId = params.getByKey(TreeParam.TREE_AID);
		textOperatorId = params.getByKey(TreeParam.NODE_TEXT_OPEERATORID);
		nodeId = params.getByKey(TreeParam.NODE_ID);
		realId = params.getByKey(TreeParam.NODE_REAL_ID);
		nodeCId = params.getByKey(TreeParam.NODE_CONTARINER_ID);
	}
	
	/**
	 * 取索引表字段对象
	 * @throws ErrorMessage
	 */
	private void getTreeIndexFields() throws ErrorMessage{
		TOOLS.checkNull(tableName,"TreeIndex Error,tableName");
		field = TreeIndexFields.getTreeFields(tableName);
	}
	
	/**
	 * 根据设置的operatorId取节点的说明信息
	 *   <li>结果集列约定索引 0:ID 1:名称
	 * @param operatorId 操作节点id
	 * @param ID 操作表的主键id
	 * @return String 需要的节点信息字符串
	 * @throws ErrorMessage 
	 */
	private String getNodeText(String operatorId,String ID) throws ErrorMessage{
		OperatorResult or = Operator.get(operatorId, SysName.SysUser, new DataFilter(ID));
		if(TOOLS.exist(or)){
			return or.getValue(1);
		}
		return null;
	}
}
